package com.zmn.uac.business.impl.oauth.login;

import com.alibaba.fastjson.JSONObject;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.consts.GateTypeConsts;
import com.zmn.consts.GlobalConsts;
import com.zmn.saas.dubbo.dto.app.AppDRO;
import com.zmn.uac.business.interfaces.oauth.login.WeChatAppLoginBService;
import com.zmn.uac.business.template.oauth.login.BaseLoginTemplateMode;
import com.zmn.uac.common.constant.AccessTypeConstant;
import com.zmn.uac.common.constant.WeChatUrlConstant;
import com.zmn.uac.common.dio.oauth.login.TempCodeDIO;
import com.zmn.uac.common.dio.oauth.login.UserAuthLoginDIO;
import com.zmn.uac.common.entity.oauth.login.*;
import com.zmn.uac.common.entity.oauth.phone.UserPhoneInfo;
import com.zmn.uac.common.info.UserAuthPhoneInfo;
import com.zmn.uac.common.info.wechat.WeChatOfficialAccountUserInfo;
import com.zmn.uac.common.info.wechat.WeChatUserAuthInfo;
import com.zmn.uac.util.HttpClientsUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * 类描述：微信APP登陆业务实现
 *
 * @author xujie
 * @since 2021/06/17 10:26
 */
@Slf4j
@Service
public class WeChatAppLoginBServiceImpl extends BaseLoginTemplateMode implements WeChatAppLoginBService {

    private static final String TAG = "微信APP登陆业务实现";

    @Override
    public ResponseDTO<UserAuthLoginInfo> thirdPartyUserDataAcquisition(UserAuthLoginDIO dio, UserAuthPhoneInfo authPhoneInfo) {
        WeChatUserAuthInfo info = (WeChatUserAuthInfo) authPhoneInfo;
        String requestUserInfoUrl = String.format(WeChatUrlConstant.SNS_USER_INFO_URL, info.getToken(), info.getToken());
        String jsonResult = HttpClientsUtil.executeGet(requestUserInfoUrl);
        if (jsonResult == null) {
            return ResponseDTO.fail("获取用户信息异常");
        }
        WeChatOfficialAccountUserInfo accountUserInfo = JSONObject.parseObject(jsonResult, WeChatOfficialAccountUserInfo.class);
        if (accountUserInfo == null || accountUserInfo.getOpenid() == null) {
            log.error("[{}], 获取用户信息失败参数:{}, jsonResult：{}", TAG, JSONObject.toJSONString(info), jsonResult);
            return ResponseDTO.fail("获取用户信息失败");
        }

        Integer channelId = dio.getChannelId();
        AppDRO app = Objects.equals(dio.getAccessType(), AccessTypeConstant.SHOP)
                ? getAppInfoByShopId(dio.getShopId()) : getAppByChannelId(channelId);
        if (app == null) {
            return ResponseDTO.fail("查询应用为null");
        }
        Integer gender = (accountUserInfo.getSex() != null && accountUserInfo.getSex() != 0) ? accountUserInfo.getSex() : 3;
        UserInfo userInfo = setUserInfo(info, accountUserInfo, dio, gender);
        PlatInfo platInfo = setPlatInfo(dio, app, channelId);
        ThirdAppInfo thirdAppInfo = setThirdAppInfo(app);
        UserOtherInfo userOtherInfo = setUserOtherInfo(accountUserInfo);
        UserAuthLoginInfo userAuthLoginInfo = setUserAuthLoginInfo(userInfo, userOtherInfo, platInfo, thirdAppInfo);

        return ResponseDTO.success(userAuthLoginInfo);
    }

    @Override
    public ResponseDTO<String> getThirdPartyOpenIdByCode(TempCodeDIO tempCodeDIO, AppDRO app) {
        return null;
    }


    private UserInfo setUserInfo(WeChatUserAuthInfo info,WeChatOfficialAccountUserInfo accountUserInfo,UserAuthLoginDIO dio,Integer gender){
        return UserInfo.builder()
                .openId(info.getOpenid())
                .unionId(accountUserInfo.getUnionId() == null ? info.getOpenid() : accountUserInfo.getUnionId())
                .type(GlobalConsts.NO)
                .realname(StringUtil.isBlank(accountUserInfo.getNickname()) ? "微信用户" : dio.getNickName())
                .username(null)
                .nickName(accountUserInfo.getNickname())
                .avatarSrc(StringUtils.isNotBlank(accountUserInfo.getHeadImgUrl()) ? accountUserInfo.getHeadImgUrl() : accountUserInfo.getAvatarUrl())
                .gender(gender)
                .country(accountUserInfo.getCountry())
                .province(accountUserInfo.getProvince())
                .city(accountUserInfo.getCity())
                .build();
    }

    private PlatInfo setPlatInfo(UserAuthLoginDIO dio,AppDRO app,Integer channelId){
        return PlatInfo.builder()
                .shopId(dio.getShopId())
                .plat(app.getPlat())
                .channelId(channelId)
                .channelName(getNameByChannelId(channelId))
                .entrance(dio.getEntrance())
                .build();
    }

    private ThirdAppInfo setThirdAppInfo(AppDRO app){
        return ThirdAppInfo.builder()
                .appId(app.getThirdAppId())
                .appName(app.getName())
                .appSecret(app.getThirdAppSecret())
                .build();
    }

    private UserOtherInfo setUserOtherInfo(WeChatOfficialAccountUserInfo accountUserInfo){
        return UserOtherInfo.builder()
                .language(accountUserInfo.getLanguage())
                .build();
    }

    private UserAuthLoginInfo setUserAuthLoginInfo(UserInfo userInfo,UserOtherInfo userOtherInfo,PlatInfo platInfo,ThirdAppInfo thirdAppInfo){
        return UserAuthLoginInfo.builder()
                .userInfo(userInfo)
                .userOtherInfo(userOtherInfo)
                .platInfo(platInfo)
                .thirdAppInfo(thirdAppInfo)
                .userPhoneInfo(new UserPhoneInfo())
                .build();
    }
}
